/**
 * 
 */
package weather.util.dictionary;

import static org.junit.Assert.*;

import java.io.*;
import java.util.*;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.junit.*;

import weather.language.forecast.*;

/**
 * Test method for {@link weather.util.dictionary.AbstractGroupingDictionary}.
 * @author Jerzy Mazurek WEiTI PW
 */
public class AbstractGroupingDictionaryTest
{
	@BeforeClass
	public static void setUpBeforeClass() throws Exception
	{
		initializeTestConditions();
		
		Workbook wb = new HSSFWorkbook();
		Sheet sheet = wb.createSheet();
		
		Row groupsRow = sheet.createRow(0);
		
		int c = 1;
		groupsRow.createCell(0).setCellValue("");
		for (ConditionsGroup group: testGroups.values())
			groupsRow.createCell(c++).setCellValue(group.getId());
		
		int r = 1;
		for (Condition condition: testConditions.values())
		{
			Row row = sheet.createRow(r++);
			row.createCell(0).setCellValue(condition.getDescription());
			
			c = 1;
			for (ConditionsGroup group: testGroups.values())
				if (condition.belongsToGroup(group))
					row.createCell(c++).setCellValue(1);
				else
					row.createCell(c++).setCellValue(0);
		}
		
		OutputStream out = new BufferedOutputStream(new FileOutputStream(testXlsFile));
		wb.write(out);
		out.close();
	}
	
	@AfterClass
	public static void tearDownAfterClass() throws Exception
	{
		testXlsFile.delete();
	}

	/**
	 * Test method for {@link weather.util.dictionary.AbstractGroupingDictionary#loadFromXlsFile(java.io.File, int)}.
	 */
	@Test
	public void testLoadFromXlsFile()
	{
		TestDictionary dict = new TestDictionary();
		
		try
		{
			dict.loadFromXlsFile(testXlsFile, 0);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			fail();
		}
		
		assertDictionaryCorrect(dict);
		
		try
		{
			dict.loadFromXlsFile(testXlsFile, 0);
		}
		catch (IOException e)
		{
			e.printStackTrace();
			fail();
		}
		
		assertDictionaryCorrect(dict);
	}
	
	private static void initializeTestConditions()
	{
		testGroups.put("RAIN", new ConditionsGroup("RAIN"));
		testGroups.put("SLEET", new ConditionsGroup("SLEET"));
		testGroups.put("SNOW", new ConditionsGroup("SNOW"));
		
		testConditions.put("RAIN", new Condition("RAIN"));
		testConditions.put("CHANCE_OF_RAIN", new Condition("CHANCE_OF_RAIN"));
		testConditions.put("SLEET", new Condition("SLEET"));
		testConditions.put("CHANCE_OF_SLEET", new Condition("CHANCE_OF_SLEET"));
		testConditions.put("SNOW", new Condition("SNOW"));
		testConditions.put("CHANCE_OF_SNOW", new Condition("CHANCE_OF_SNOW"));
		
		testGroups.get("RAIN").addCondition(testConditions.get("RAIN"));
		testGroups.get("RAIN").addCondition(testConditions.get("CHANCE_OF_RAIN"));
		testGroups.get("RAIN").addCondition(testConditions.get("SLEET"));
		testGroups.get("RAIN").addCondition(testConditions.get("CHANCE_OF_SLEET"));
		testGroups.get("SLEET").addCondition(testConditions.get("SLEET"));
		testGroups.get("SLEET").addCondition(testConditions.get("CHANCE_OF_SLEET"));
		testGroups.get("SNOW").addCondition(testConditions.get("SLEET"));
		testGroups.get("SNOW").addCondition(testConditions.get("CHANCE_OF_SLEET"));
		testGroups.get("SNOW").addCondition(testConditions.get("SNOW"));
		testGroups.get("SNOW").addCondition(testConditions.get("CHANCE_OF_SNOW"));
	}
	
	private static void assertDictionaryCorrect(TestDictionary dict)
	{
		int i = 0;
		for (ConditionsGroup testGroup: testGroups.values())
			for (ConditionsGroup dictGroup: dict.getGroups())
				if (testGroup.equals(dictGroup))
				{
					++i;
					assertEquals(testGroup.getConditions(), dictGroup.getConditions());
				}
		assertEquals(testGroups.values().size(), i);
	}

	private static File testXlsFile = new File("tests/grouping_test.xls");
	private static Map<String, Condition> testConditions = new HashMap<String, Condition>();
	private static Map<String, ConditionsGroup> testGroups = new HashMap<String, ConditionsGroup>();
	
	private static class TestDictionary extends AbstractGroupingDictionary<ConditionsGroup, Condition>
	{
		@Override
		protected void addToGroup(Condition element, ConditionsGroup group)
		{
			group.addCondition(element);
		}

		@Override
		public boolean elementBelongsToGroup(Condition element,
				ConditionsGroup group)
		{
			return element.belongsToGroup(group);
		}

		@Override
		public boolean groupContainsElement(ConditionsGroup group,
				Condition element)
		{
			return group.containsCondition(element);
		}

		@Override
		protected Condition newElement(String s)
		{
			return new Condition(s);
		}

		@Override
		protected ConditionsGroup newGroup(String s)
		{
			return new ConditionsGroup(s);
		}
	}
}
